package com.qijian.framework.runner;

import com.alibaba.fastjson.JSON;
import com.qijian.common.core.domain.entity.SysMenu;
import com.qijian.common.utils.StringUtils;
import com.qijian.common.utils.spring.SpringUtils;
import com.qijian.system.service.ISysMenuService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.ListUtils;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.mvc.method.RequestMappingInfo;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Component
@RequiredArgsConstructor
@Slf4j
@Order(Ordered.HIGHEST_PRECEDENCE)
public class PermValidate implements ApplicationRunner {

    private final ISysMenuService menuService;

    @Override
    public void run(ApplicationArguments args) throws Exception {
        List<SysMenu> menus = menuService.selectMenuList(1L);
        List<String> permList = menus.stream().map(SysMenu::getPerms).filter(ObjectUtils::isNotEmpty).collect(Collectors.toList());

        List<String> normalList = new ArrayList<>();
        List<String> errorList = new ArrayList<>();

        RequestMappingHandlerMapping rm = SpringUtils.getBean(RequestMappingHandlerMapping.class);
        Map<RequestMappingInfo, HandlerMethod> handlerMethods = rm.getHandlerMethods();

        handlerMethods.values().forEach(v -> {
            PreAuthorize auth = v.getMethodAnnotation(PreAuthorize.class);
            if (auth != null) {
                String permStr = StringUtils.substringBetween(auth.value(), "('", "')");
                String[] splitPerm = permStr.split(",");
//                for (String s : splitPerm) {
//                    if (!permList.contains(s)) {
//                        errorList.add(s);
//                    } else
//                        normalList.add(s);
//                }
            }
        });
        permList.removeAll(ListUtils.union(normalList, errorList));
        if (CollectionUtils.isNotEmpty(permList))
//            log.warn("has not used Perm in database:{}", JSON.toJSONString(permList));
        if (CollectionUtils.isNotEmpty(errorList)) {
            String msg = JSON.toJSONString(errorList);
            log.error("@PreAuthorize has not insert database perm:{}", msg);
            throw new RuntimeException("存在无法使用的功能，无法启动项目，请根据验证信息，处理完再启动！\n" + msg);
        }
    }
}
